package com.alstudio.module.xmpp.protocol.xmpp.util.xmlcreator.iq;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import android.text.TextUtils;

import com.alstudio.module.xmpp.protocol.xmpp.ALXMLGenerator;
import com.alstudio.module.xmpp.protocol.xmpp.util.PackactIdGenerator;
import com.alstudio.module.xmpp.protocol.xmpp.util.xmlcreator.AlBaseXmlCreator;
import com.alstudio.module.xmpp.protocol.xmpp.util.xmlcreator.AlXmlTag;
import com.alstudio.utils.log.ALLog;

/**
 * ALIQCreator用于快速创建缺省类型为"set"IQ的xml字符串。请注意，to、ns、tagList为必填项！
 * 
 * @author alonso lee
 * 
 */
public class ALIQCreator extends AlBaseXmlCreator {

	// 缺省自构造的iq节点
	private AlXmlTag iqTag;
	// 缺省自构造的query节点
	private AlXmlTag queryTag;
	private String type = "set";
	private String to;
	private String from;
	private String ns;
	private final int ID_DEFAULT_LEN = 10;
	private ArrayList<AlXmlTag> tagList;

	public ALIQCreator() {
		// TODO Auto-generated constructor stub
		iqTag = new AlXmlTag("iq");
		queryTag = new AlXmlTag("query");
		iqTag.setAtts(getDefaultIqTagAtt());
		queryTag.setAtts(getDefaultQueryTagAtt());
	}

	/**
	 * 获取IQ类型
	 * 
	 * @return 取值有"set"、"get"、"result"
	 */
	public String getType() {
		return type;
	}

	/**
	 * 设置IQ类型
	 * 
	 * @param type
	 *            取值有"set"、"get"、"result"
	 */
	public void setType(String type) {
		this.type = type;
	}

	/**
	 * 本条IQ接收者
	 * 
	 * @return
	 */
	public String getTo() {
		return to;
	}

	/**
	 * 必填项，本条IQ接收者
	 * 
	 * @param to
	 */
	public void setTo(String to) {
		this.to = to;
	}

	/**
	 * 获取本条IQ发送者
	 * 
	 * @return
	 */
	public String getFrom() {
		return from;
	}

	/**
	 * 设置本条IQ发送者
	 * 
	 * @param from
	 */
	public void setFrom(String from) {
		this.from = from;
	}

	/**
	 * 获取命名空间
	 * 
	 * @return
	 */
	public String getNs() {
		return ns;
	}

	/**
	 * 设置命名空间，必填项 ！
	 * 
	 * @param ns
	 */
	public void setNs(String ns) {
		this.ns = ns;
	}

	/**
	 * 设置节点集合，此为必填项!
	 * 
	 * @param tagList
	 */
	public void setTagList(ArrayList<AlXmlTag> tagList) {
		this.tagList = tagList;
	}

	/**
	 * 创建缺省iq节点属性。目前仅有‘id’属性。
	 * 
	 * @return
	 */
	private HashMap<String, String> getDefaultIqTagAtt() {
		HashMap<String, String> iqTagAtts = new HashMap<String, String>();
		iqTagAtts.put("id", PackactIdGenerator.getPackactIdGenerator()
				.getPackactId(ID_DEFAULT_LEN));

		return iqTagAtts;
	}

	/**
	 * 创建缺省query节点属性。目前仅有'xmlns'
	 * 
	 * @return
	 */
	private HashMap<String, String> getDefaultQueryTagAtt() {
		HashMap<String, String> queryTagAtts = new HashMap<String, String>();
		queryTagAtts.put("xmlns", "");

		return queryTagAtts;
	}

	@Override
	public String getXml() throws Exception {
		// TODO Auto-generated method stub

		if (!TextUtils.isEmpty(xml)) {
			return xml;
		}

		if (TextUtils.isEmpty(to)) {
			ALLog.e("iq中的to属性不能为空");
			throw new Exception("iq中的to属性不能为空");
		}

		if (TextUtils.isEmpty(ns)) {
			ALLog.e("query中的ns属性不能为空");
			throw new Exception("query中的ns属性不能为空");
		}

		// 设置to属性
		iqTag.getAtts().put("to", to);

		if (!TextUtils.isEmpty(from)) {
			// 设置from属性
			iqTag.getAtts().put("from", from);
		}

		// 设置type属性
		iqTag.getAtts().put("type", type);

		// 设置query
		queryTag.getAtts().put("xmlns", ns);

		if (tagList == null) {
			throw new Exception("节点队列不能为空，请调用'setTagList'设置节点队列");
		}
		xmlCreator = new ALXMLGenerator();

		startCreateXml();
		xml = new String(xmlCreator.getXml());
		xmlCreator.release();
		xmlCreator = null;
		return xml;
	}

	private void startCreateXml() throws Exception {

		// 创建iq、query节点
		createBaseTag();

		// 创建其他节点
		for (AlXmlTag tag : tagList) {
			createTag(tag, !tag.isHasSubTag());
		}

		for (AlXmlTag tag : tagList) {
			if (tag.isHasSubTag()) {
				xmlCreator.endTag();
			}
		}

		// 创建query结束
		xmlCreator.endTag();
		// 创建iq结束
		xmlCreator.endTag();
		ALLog.i("xml创建完成: " + xmlCreator.getXml());
	}

	private void createBaseTag() throws IOException {

		// 顺序不能乱，先创建iq
		createTag(iqTag, false);
		// 再创建query
		createTag(queryTag, false);

	}

	private void createTag(AlXmlTag tag, boolean endTag) throws IOException {
		if (tag == null) {
			ALLog.e("传入的AlXmlTag对象为空!");
			return;
		}

		Iterator<Entry<String, String>> it = null;

		// ALLog.i("开始拼装 " + tag.getTagName());
		xmlCreator.startTag(tag.getTagName());

		Map<String, String> tagAtts = tag.getAtts();

		if (tagAtts != null && tagAtts.size() > 0) {
			it = tagAtts.entrySet().iterator();
			// 写入属性
			while (it.hasNext()) {
				Entry<String, String> entry = (Entry<String, String>) it.next();
				xmlCreator.attribute(entry.getKey(), entry.getValue());
			}

			it = null;
		}

		if (!TextUtils.isEmpty(tag.getText())) {
			xmlCreator.text(tag.getText());
		} else {
		}

		ALLog.i(tag.getTagName() + " 拼装完成");
		if (endTag) {
			xmlCreator.endTag();
			ALLog.i("结束节点 " + tag.getTagName());
		}

	}
}
